"""
笔记服务 API
所有接口采用 POST 方法，统一响应格式
包含自动数据权限隔离
"""
from fastapi import APIRouter, Depends, Request
from motor.motor_asyncio import AsyncIOMotorDatabase
from pydantic import BaseModel, Field
from typing import List, Optional
from bson import ObjectId
from datetime import datetime

from database.connection import get_database
from models.note import NoteOut, NoteCreate, NoteUpdate
from api.deps_v1 import get_current_user
from utils.response import success, error
from models.response import ErrorCode

router = APIRouter(prefix="/sac/v1/Note", tags=["笔记服务"])

# 服务名称
SERVICE_NAME = "Note"


# ========== 请求模型 ==========

class CreateNoteRequest(BaseModel):
    """创建笔记请求"""
    title: str = Field(..., min_length=1, max_length=200)
    content: str


class ListNotesRequest(BaseModel):
    """获取笔记列表请求"""
    skip: int = Field(default=0, ge=0, description="跳过记录数")
    limit: int = Field(default=10, ge=1, le=100, description="返回记录数")


class GetNoteRequest(BaseModel):
    """获取笔记详情请求"""
    note_id: str = Field(..., description="笔记ID")


class UpdateNoteRequest(BaseModel):
    """更新笔记请求"""
    note_id: str = Field(..., description="笔记ID")
    title: Optional[str] = Field(None, min_length=1, max_length=200)
    content: Optional[str] = None


class DeleteNoteRequest(BaseModel):
    """删除笔记请求"""
    note_id: str = Field(..., description="笔记ID")


# ========== 响应模型 ==========

class CreateNoteResult(BaseModel):
    """创建笔记结果"""
    note: NoteOut


class ListNotesResult(BaseModel):
    """笔记列表结果"""
    notes: List[NoteOut]
    total: int
    skip: int
    limit: int


class GetNoteResult(BaseModel):
    """笔记详情结果"""
    note: NoteOut


class UpdateNoteResult(BaseModel):
    """更新笔记结果"""
    note: NoteOut


class DeleteNoteResult(BaseModel):
    """删除笔记结果"""
    message: str
    note_id: str


# ========== API 接口 ==========

@router.post("/CreateNote", summary="创建笔记")
async def create_note(
    request: Request,
    body: CreateNoteRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_database)
):
    """
    创建新笔记
    
    **自动数据隔离**: 笔记自动关联到当前用户
    """
    try:
        # 构建笔记数据（自动注入 user_id）
        note_data = {
            "title": body.title,
            "content": body.content,
            "user_id": current_user["id"],  # 自动注入
            "created_at": datetime.utcnow(),
            "updated_at": None
        }
        
        # 插入数据库
        result = await db.notes.insert_one(note_data)
        
        # 查询新创建的笔记
        new_note = await db.notes.find_one({"_id": result.inserted_id})
        new_note["id"] = str(new_note.pop("_id"))
        
        return success(
            request, "CreateNote", SERVICE_NAME,
            CreateNoteResult(note=NoteOut(**new_note)).model_dump()
        )
        
    except Exception as e:
        return error(
            request, "CreateNote", SERVICE_NAME,
            ErrorCode.SYSTEM_ERROR,
            detail=str(e)
        )


@router.post("/ListNotes", summary="获取我的笔记列表")
async def list_notes(
    request: Request,
    body: ListNotesRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_database)
):
    """
    获取当前用户的笔记列表（分页）
    
    **自动数据隔离**: 只返回当前用户的笔记
    """
    try:
        # 查询条件（自动注入 user_id）
        query = {"user_id": current_user["id"]}
        
        # 查询总数
        total = await db.notes.count_documents(query)
        
        # 查询笔记列表
        cursor = db.notes.find(query).skip(body.skip).limit(body.limit).sort("created_at", -1)
        notes = await cursor.to_list(length=body.limit)
        
        # 转换数据格式
        note_list = []
        for note in notes:
            note["id"] = str(note.pop("_id"))
            note_list.append(NoteOut(**note))
        
        return success(
            request, "ListNotes", SERVICE_NAME,
            ListNotesResult(
                notes=note_list,
                total=total,
                skip=body.skip,
                limit=body.limit
            ).model_dump()
        )
        
    except Exception as e:
        return error(
            request, "ListNotes", SERVICE_NAME,
            ErrorCode.SYSTEM_ERROR,
            detail=str(e)
        )


@router.post("/GetNote", summary="获取笔记详情")
async def get_note(
    request: Request,
    body: GetNoteRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_database)
):
    """
    获取指定笔记的详细信息
    
    **自动数据隔离**: 只能查看自己的笔记
    """
    try:
        # 验证 ObjectId 格式
        if not ObjectId.is_valid(body.note_id):
            return error(
                request, "GetNote", SERVICE_NAME,
                ErrorCode.INVALID_PARAMETER,
                detail="无效的笔记ID格式"
            )
        
        # 查询笔记（自动注入 user_id）
        note = await db.notes.find_one({
            "_id": ObjectId(body.note_id),
            "user_id": current_user["id"]  # 防止越权访问
        })
        
        if not note:
            return error(
                request, "GetNote", SERVICE_NAME,
                ErrorCode.RESOURCE_NOT_FOUND,
                message="笔记不存在"
            )
        
        note["id"] = str(note.pop("_id"))
        
        return success(
            request, "GetNote", SERVICE_NAME,
            GetNoteResult(note=NoteOut(**note)).model_dump()
        )
        
    except Exception as e:
        return error(
            request, "GetNote", SERVICE_NAME,
            ErrorCode.SYSTEM_ERROR,
            detail=str(e)
        )


@router.post("/UpdateNote", summary="更新笔记")
async def update_note(
    request: Request,
    body: UpdateNoteRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_database)
):
    """
    更新指定笔记
    
    **自动数据隔离**: 只能更新自己的笔记
    """
    try:
        # 验证 ObjectId 格式
        if not ObjectId.is_valid(body.note_id):
            return error(
                request, "UpdateNote", SERVICE_NAME,
                ErrorCode.INVALID_PARAMETER,
                detail="无效的笔记ID格式"
            )
        
        # 构建更新数据
        update_data = {"updated_at": datetime.utcnow()}
        if body.title is not None:
            update_data["title"] = body.title
        if body.content is not None:
            update_data["content"] = body.content
        
        # 更新笔记（自动注入 user_id）
        result = await db.notes.update_one(
            {
                "_id": ObjectId(body.note_id),
                "user_id": current_user["id"]  # 防止越权修改
            },
            {"$set": update_data}
        )
        
        if result.matched_count == 0:
            return error(
                request, "UpdateNote", SERVICE_NAME,
                ErrorCode.RESOURCE_NOT_FOUND,
                message="笔记不存在或无权限"
            )
        
        # 查询更新后的笔记
        updated_note = await db.notes.find_one({"_id": ObjectId(body.note_id)})
        updated_note["id"] = str(updated_note.pop("_id"))
        
        return success(
            request, "UpdateNote", SERVICE_NAME,
            UpdateNoteResult(note=NoteOut(**updated_note)).model_dump()
        )
        
    except Exception as e:
        return error(
            request, "UpdateNote", SERVICE_NAME,
            ErrorCode.SYSTEM_ERROR,
            detail=str(e)
        )


@router.post("/DeleteNote", summary="删除笔记")
async def delete_note(
    request: Request,
    body: DeleteNoteRequest,
    current_user: dict = Depends(get_current_user),
    db: AsyncIOMotorDatabase = Depends(get_database)
):
    """
    删除指定笔记
    
    **自动数据隔离**: 只能删除自己的笔记
    """
    try:
        # 验证 ObjectId 格式
        if not ObjectId.is_valid(body.note_id):
            return error(
                request, "DeleteNote", SERVICE_NAME,
                ErrorCode.INVALID_PARAMETER,
                detail="无效的笔记ID格式"
            )
        
        # 删除笔记（自动注入 user_id）
        result = await db.notes.delete_one({
            "_id": ObjectId(body.note_id),
            "user_id": current_user["id"]  # 防止越权删除
        })
        
        if result.deleted_count == 0:
            return error(
                request, "DeleteNote", SERVICE_NAME,
                ErrorCode.RESOURCE_NOT_FOUND,
                message="笔记不存在或无权限"
            )
        
        return success(
            request, "DeleteNote", SERVICE_NAME,
            DeleteNoteResult(
                message="笔记删除成功",
                note_id=body.note_id
            ).model_dump()
        )
        
    except Exception as e:
        return error(
            request, "DeleteNote", SERVICE_NAME,
            ErrorCode.SYSTEM_ERROR,
            detail=str(e)
        )

